package com.qianda.qdminiapp.service.order;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qianda.qdminiapp.common.constant.CommonConstant;
import com.qianda.qdminiapp.common.rabbitmq.MsgProducer;
import com.qianda.qdminiapp.common.util.DateUtils;
import com.qianda.qdminiapp.dao.account.QqdAccountDao;
import com.qianda.qdminiapp.dao.account.QqdAccountTradeDao;
import com.qianda.qdminiapp.dao.device.DeviceDao;
import com.qianda.qdminiapp.dao.device.QqdDeviceDao;
import com.qianda.qdminiapp.dao.device.QqdStoreDao;
import com.qianda.qdminiapp.dao.order.OrderDao;
import com.qianda.qdminiapp.dao.order.QqdOrderInfoDao;
import com.qianda.qdminiapp.dao.order.QqdOrderTowelDao;
import com.qianda.qdminiapp.dao.personmanage.QqdCompanyDao;
import com.qianda.qdminiapp.dao.user.QqdUserDao;
import com.qianda.qdminiapp.dao.user.UserDao;
import com.qianda.qdminiapp.domain.dto.OrderAndPayDto;
import com.qianda.qdminiapp.domain.model.account.QqdAccount;
import com.qianda.qdminiapp.domain.model.account.QqdAccountTrade;
import com.qianda.qdminiapp.domain.model.device.Device;
import com.qianda.qdminiapp.domain.model.device.QqdDevice;
import com.qianda.qdminiapp.domain.model.order.Order;
import com.qianda.qdminiapp.domain.model.order.QqdOrderInfo;
import com.qianda.qdminiapp.domain.model.order.QqdOrderTowel;
import com.qianda.qdminiapp.domain.model.user.QqdUser;
import com.qianda.qdminiapp.domain.model.user.User;
import com.qianda.qdminiapp.common.exception.ExceptionCode;
import com.qianda.qdminiapp.common.exception.SimpleException;
import com.qianda.qdminiapp.security.LoginFilter;
import com.qianda.qdminiapp.service.CommondManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * 余额支付
 * @ClassName BalancePaymentImpl
 * @Author cw
 * @Date 2019/8/7 14:23
 * @Version 1.0
 */
public class BalancePaymentImpl extends AbstractOrderAndPay {

    private QqdAccountDao qqdAccountDao;
    private static Logger LOGGER = LoggerFactory.getLogger(BalancePaymentImpl.class);

    public BalancePaymentImpl(QqdUserDao userDao, QqdOrderInfoDao orderInfoDao, QqdOrderTowelDao qqdOrderTowelDao,
                              CommondManager commondManager, QqdDeviceDao deviceDao,
                              QqdAccountDao qqdAccountDao, QqdStoreDao qqdStoreDao, QqdAccountTradeDao qqdAccountTradeDao,
                              MsgProducer msgProducer, QqdCompanyDao qqdCompanyDao) {
        super(userDao, orderInfoDao,qqdOrderTowelDao, commondManager, deviceDao,qqdStoreDao,qqdAccountTradeDao,msgProducer,qqdCompanyDao);
        this.qqdAccountDao = qqdAccountDao;
    }

    /*
     * 余额支付前置校验方法
     * @Description
     * @Author cw
     * @Date 14:24 2019/8/7
     * @Param []
     * @return boolean
     **/
    @Override
    public boolean checkStatus(OrderAndPayDto orderAndPayDto) {
        // 查询用户余额，判断是否足够支付此次交易
        QqdUser user = userDao.selectById(orderAndPayDto.getUserId());
        QueryWrapper<QqdAccount> qqdAccountQueryWrapper = new QueryWrapper<>();
        qqdAccountQueryWrapper.eq("user_id",user.getId()).eq("status",CommonConstant.Status.STATUS_NORMAL);
        QqdAccount qqdAccount = qqdAccountDao.selectOne(qqdAccountQueryWrapper);

        BigDecimal balance = qqdAccount.getBalance();
        QqdDevice device = deviceDao.selectById(orderAndPayDto.getDeviceId());
        BigDecimal payMoney =orderAndPayDto.getPayMoney();
        // 计算该笔交易金额
        if (balance.compareTo(payMoney)<0) {
            LOGGER.error("用户余额不足");
           throw new SimpleException(ExceptionCode.EX_USER_BALLANCE_NOT_ENOUGH);
        }
        return true;
    }

    /*
     * 余额支付
     * @Description
     * @Author cw
     * @Date 14:43 2019/8/7
     * @Param [order]
     * @return void
     **/
    @Override
    public Map<String,Object> appPay(QqdOrderInfo orderInfo) {

        QueryWrapper<QqdOrderTowel> qqdOrderTowelQueryWrapper = new QueryWrapper<>();
        qqdOrderTowelQueryWrapper.eq("order_id",orderInfo.getId()).eq("status",CommonConstant.Status.STATUS_NORMAL);
        QqdOrderTowel order = qqdOrderTowelDao.selectOne(qqdOrderTowelQueryWrapper);

        QqdUser user = userDao.selectById(order.getOrderUserId());
        QqdAccount qqdAccount = qqdAccountDao.selectById(user.getAccountId());

        Map<String,Object> param = new HashMap();
        param.put("orderMoney",order.getOrderAmt());
        param.put("userId",order.getOrderUserId());

        //新增一条交易明细
        QqdAccountTrade qqdAccountTrade = new QqdAccountTrade();
        qqdAccountTrade.setUserId(order.getOrderUserId());
        qqdAccountTrade.setAccountId(user.getAccountId());
        qqdAccountTrade.setTradeType(CommonConstant.TradeType.TRADE_TYPE_BUY_TOWEL);
        qqdAccountTrade.setTradeState(CommonConstant.TradeState.TRADE_STATE_OUT);
        qqdAccountTrade.setTradeMode(CommonConstant.TradeMode.TRADE_MODEL_WALLET);
        qqdAccountTrade.setTradeTime(LocalDateTime.now());
        qqdAccountTrade.setTradeBeforeAmt(qqdAccount.getBalance());
        qqdAccountTrade.setTradeAmt(order.getOrderAmt());
        qqdAccountTrade.setStatus(CommonConstant.Status.STATUS_NORMAL);
        qqdAccountTrade.setCreateTime(LocalDateTime.now());
        qqdAccountTradeDao.insert(qqdAccountTrade);

        //减余额
        int banlancePayResult = userDao.descUserMoney(param);
        if (banlancePayResult < 1) {
            LOGGER.error("支付失败");
            //余额支付失败
           throw new SimpleException(ExceptionCode.EX_USER_BALLANCE_PAY_ERROR);
        }
        order.setOrderPayTime(LocalDateTime.now());
        order.setOrderPayType(CommonConstant.PayType.PAY_TYPE_BALANCE);
        order.setOrderPayStatus(CommonConstant.PayStatus.PAY_STATUS_PAYED);
        order.setOrderStatus(CommonConstant.OrderOutTowelStatus.ORDER_OUT_TOWEL_STATUS_WORKING);
        order.setUpdateTime(LocalDateTime.now());
        qqdOrderTowelDao.updateById(order);
        return null;
    }

    /*
     * 余额退款
     * @Description
     * @Author cw
     * @Date 11:49 2019/8/9
     * @Param [order]
     * @return void
     **/
    @Override
    public void refundPay(QqdOrderTowel order) {
        QqdOrderTowel qqdOrderTowel = qqdOrderTowelDao.selectById(order.getId());
        if(qqdOrderTowel.getOrderPayStatus() == CommonConstant.PayStatus.PAY_STATUS_REFUND ){
            return;
        }

        //用户余额返还
        userDao.setUserMoney(order.getOrderAmt(),order.getOrderUserId());

        //订单支付状态改为已退款
        qqdOrderTowel.setOrderPayStatus(CommonConstant.PayStatus.PAY_STATUS_REFUND);
        qqdOrderTowelDao.updateById(qqdOrderTowel);
    }
}
